/**
 * Ingenius-Group S.A.S
 *
 * Project: SAU
 * File: JdoUserDAO.java
 * Date: 01/03/2011
 */

package com.ingenius.sau.server.persistence.jdo;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;

import com.ingenius.sau.server.persistence.UserDAO;
import com.ingenius.sau.shared.model.users.Role;
import com.ingenius.sau.shared.model.users.User;
import com.ingenius.sau.shared.util.filter.Comparison;
import com.ingenius.sau.shared.util.filter.Filter;
import com.ingenius.sau.shared.util.filter.StringFilter;

/**
 * Class <strong>JdoUserDAO</strong>
 * 
 * @author Jesus David
 * @version 0.1
 */
public class JdoUserDAO implements UserDAO {

	private static Logger logger = Logger.getLogger(JdoFactorDAO.class
			.getName());

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ingenius.sau.server.persistence.DAO#save(java.lang.Object)
	 */
	@Override
	public Boolean save(User object) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Transaction tx = pm.currentTransaction();
		Boolean result = false;
		try {
			logger.info("Saving object...");
			tx.begin();
			String id = object.getRole().getId();
			object.setRole(null);
			Role role = pm.getObjectById(Role.class, id);
			role.addUser(object);
			pm.makePersistent(object);
			tx.commit();
			result = true;
			logger.fine("ok -> object saved [" + object + "]");

		} catch (Exception e) {
			String msg = "Failed to save user [" + object + "]. ";
			logger.log(Level.SEVERE, msg, e);
			System.out.println(msg + e.getMessage());

		} finally {
			if (tx.isActive()) {
				tx.rollback();
			}
			pm.close();
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ingenius.sau.server.persistence.DAO#update(java.lang.Object)
	 */
	@Override
	public Boolean update(User copy) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Transaction tx = pm.currentTransaction();
		Boolean result = false;
		try {
			logger.info("Updating object...");
			tx.begin();
			User save = pm.getObjectById(User.class, copy.getId());
			save.setUsername(copy.getUsername());
			save.setPassword(copy.getPassword());
			save.setPasswordChangeRequired(copy.isPasswordChangeRequired());
			save.setPerson(copy.getPerson());
			// TODO setRole
			tx.commit();
			result = true;
			logger.fine("ok -> object updated [" + save + "]");

		} catch (Exception e) {
			String msg = "Failed to update user [" + copy + "]. ";
			logger.log(Level.SEVERE, msg, e);
			System.out.println(msg + e.getMessage());

		} finally {
			if (tx.isActive()) {
				tx.rollback();
			}
			pm.close();
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ingenius.sau.server.persistence.DAO#delete(java.lang.String)
	 */
	@Override
	public Boolean delete(String id) {
		return JdoUtil.delete(User.class, id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ingenius.sau.server.persistence.DAO#get(java.lang.String)
	 */
	@Override
	public User get(String id) {
		return JdoUtil.get(User.class, id, "with_person_and_role");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ingenius.sau.server.persistence.DAO#count(java.lang.List)
	 */
	@Override
	public Integer count(List<Filter> filters) {
		return JdoUtil.count(User.class, filters);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ingenius.sau.server.persistence.DAO#getRange(java.util.List,
	 * java.lang.String, int, int)
	 */
	@Override
	public List<User> getRange(List<Filter> filters, String orderBy, int start,
			int limit) {

		return JdoUtil.getRange(User.class, filters, orderBy, start, limit,
				"with_person_and_role");
	}

	@Override
	public boolean authenticate(String username, String password) {
		List<Filter> filters = new ArrayList<Filter>();
		filters.add(new StringFilter(Comparison.EQUALS, "username", username));
		filters.add(new StringFilter(Comparison.EQUALS, "password", password));
		List<User> result = JdoUtil.getRange(User.class, filters, null, 0, 0);

		if (result != null && result.size() == 1) {

			PersistenceManager pm = PMF.get().getPersistenceManager();
			Transaction tx = pm.currentTransaction();
			try {
				logger.info("Updating object...");
				tx.begin();
				User save = pm.getObjectById(User.class, result.get(0).getId());
				save.setLastAdmission(new Date());
				tx.commit();
				logger.fine("ok -> object updated [" + save + "]");

			} catch (Exception e) {
				String msg = "Failed to update user...";
				logger.log(Level.SEVERE, msg, e);
				System.out.println(msg + e.getMessage());

			} finally {
				if (tx.isActive()) {
					tx.rollback();
				}
				pm.close();
			}
			return true;
		}
		return false;
	}

	@Override
	public User userFor(String username) {
		List<Filter> filters = new ArrayList<Filter>();
		filters.add(new StringFilter(Comparison.EQUALS, "username", username));
		List<User> result = JdoUtil.getRange(User.class, filters, null, 0, 0,
				"with_person_and_role");

		if (result != null && result.size() == 1) {
			return result.get(0);
		}
		return null;
	}

}
